/*
遍历 Result
*/

fn main() {
    // Iter::map 操作可能失败
    let strings = vec!["tofu", "93", "18"];
    let numbers: Vec<_> = strings
        .into_iter()
        .map(|s| s.parse::<i32>())
        .collect();
    println!("Results: {:?}", numbers);

    // 一些处理这种问题的策略

    // 使用 filter_map() 忽略失败的项
    // filter_map 会调用一个函数，过滤掉为 None 的所有结果。
    println!("\nstrings2: ");
    let strings2 = vec!["tofu", "93", "18"];
    let numbers: Vec<_> = strings2
        .into_iter()
        .filter_map(|s| s.parse::<i32>().ok())
        .collect();
    println!("Results: {:?}", numbers);

    // 使用 collect() 使整个操作失败
    // Result 实现了 FromIter，因此结果的向量（Vec<Result<T, E>>）可以被
    // 转换成结果包裹着向量（Result<Vec<T>, E>）。一旦找到一个 Result::Err，遍历就被终止。
    println!("\nstrings3: ");
    let strings3 = vec!["tofu", "93", "18"];
    let numbers: Result<Vec<_>, _> = strings3
        .into_iter()
        .map(|s| s.parse::<i32>())
        .collect();
    println!("Results: {:?}", numbers);

    // 使用 Partition() 收集所有合法的值与错误
    println!("\nstrings4: ");
    let strings4 = vec!["tofu", "93", "18"];
    let (numbers, errors): (Vec<_>, Vec<_>) = strings4
        .into_iter()
        .map(|s| s.parse::<i32>())
        .partition(Result::is_ok);
    println!("Numbers: {:?}", numbers);
    println!("Errors: {:?}", errors);
}